package nl.altenpts.net.kad;

import java.security.SignatureException;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
 * Store for the distributed hash table. The signature of every value in this
 * has been checked.
 * 
 * 
 * @author Fabian van der Werf
 *
 */

public class ValueStore {
	
	/**
	 * Returns the values for key.
	 * 
	 * @param key the requested key.
	 * @return returns the values for key, null if there are no values for key.
	 */
	public Set<Value> get(byte[] key) {		
		Set<Value> values = store.get(new Key(key));
		if(values == null) {
			return null;
		} else {
			Set<Value> readonly = Collections.unmodifiableSet(values);
			return readonly;
		}
	}
	
	/**
	 * Adds a new value to this ValueStore. The value's signature is verified.
	 *  
	 * @param value the value to be added to this ValueStore.
	 * @throws SignatureException if the value's signature could not be
	 *         verified.
	 */
	public void put(Value value) throws SignatureException {
		if(!value.checkSignature()) {
			throw new SignatureException("Signature verification failed");
		}
		
		Set<Value> values = store.get(value.getKey());
		if(values == null) {
			values = new LinkedHashSet<Value>();
			values.add(value);
			store.put(value.getHashKey(), values);
		} else {		
			values.add(value);
		}
	}
	
	/**
	 * Removes a value from this ValueStore.
	 * 
	 * @param the value to be removed.
	 */
	public void remove(Value value) {
		Set<Value> values = store.get(value.getKey());
		if(values != null) {
			values.remove(value);
			if(values.isEmpty()) {
				store.remove(values);
			}
		}		
	}
	
	private Map<Key, Set<Value>> store = new HashMap<Key, Set<Value>>();
}
